import type {
  ComputeContext,
  CreateCrudOptionsProps,
  CreateCrudOptionsRet,
  ScopeContext,
} from '@fast-crud/fast-crud';

import type { Ref } from 'vue';

import type { ExtendedModalApi } from '@vben/common-ui';
import type { Undefinedable } from '@vben/types';

import type { DefTenantModel } from '#/api';

import { ref } from 'vue';
import { useRouter } from 'vue-router';

import { useAccess } from '@vben/access';

import { compute } from '@fast-crud/fast-crud';
import { Tag } from 'ant-design-vue';

import { asyncFindUrlById } from '#/api';
import cities from '#/api/common/cities.json';
import { DefTenantApi } from '#/api/devOperation/tenant/defTenant';
import { DictEnum, FileBizTypeEnum, RouteEnum } from '#/enums/commonEnum';
import { PermCode } from '#/enums/perm';
import { MultiTenantTypeEnum, TenantStatusEnum } from '#/enums/system';
import { useMessage } from '#/hooks/web/useMessage';
import { $t } from '#/locales';
import {
  backendDict,
  createdTimeColumn,
  deleteButton,
  indexColumn,
  STATE_CONSTANT_DICT,
} from '#/plugins/fast-crud/common';
import { dateUtil } from '#/utils/dateUtil';

const { VITE_GLOB_TENANT_TYPE } = import.meta.env;
const { hasPermission } = useAccess();
const permCode = PermCode.devOperation.tenant.defTenant;
interface ContextRef {
  bindUserRef: Ref<Undefinedable<ExtendedModalApi>>;
  toExamineRef: Ref<Undefinedable<ExtendedModalApi>>;
  initDataRef: Ref<Undefinedable<ExtendedModalApi>>;
  linkDataSourceRef: Ref<Undefinedable<ExtendedModalApi>>;
}

export function createCrudOptions(
  props: CreateCrudOptionsProps<DefTenantModel.DefTenantResultVO, ContextRef>,
): CreateCrudOptionsRet<DefTenantModel.DefTenantResultVO> {
  const selectedRowKeys = ref<string[]>([]);
  const { push } = useRouter();
  const { createConfirm, createMessage } = useMessage();

  return {
    crudOptions: {
      form: {
        labelCol: { span: null, style: { minWidth: '130px' } },
        wrapper: {
          is: 'a-drawer',
          width: '70%',
          draggable: false,
        },
      },
      request: {
        pageRequest: DefTenantApi.pageRequest,
        addRequest: DefTenantApi.addRequest,
        editRequest: DefTenantApi.editRequest,
        delRequest: DefTenantApi.delRequest,
        infoRequest: DefTenantApi.infoRequest,
      },
      actionbar: {
        buttons: {
          add: { show: hasPermission(permCode.add), text: '新增' },
          ...deleteButton({
            crudExpose: props.crudExpose,
            selectedRowKeys,
            role: permCode.delete,
            removeFn: DefTenantApi.removeFn,
          }),
          uploadFile: {
            text: '上传文件',
            show: hasPermission(permCode.upload),
            icon: 'ant-design:cloud-upload',
            click() {
              const input = document.createElement('input');
              input.type = 'file';
              input.addEventListener('change', async (event) => {
                const file = (event.target as HTMLInputElement).files?.item(0);
                if (file) {
                  const formData = new FormData();
                  formData.append('file', file);
                  try {
                    // 调用上传接口
                    const result = await DefTenantApi.uploadFile(formData);
                    if (result) {
                      createMessage.success('文件上传成功');
                      props.crudExpose.doRefresh();
                    }
                  } catch {
                    createMessage.error('文件上传失败');
                  }
                }
                // 清理资源：移除input元素
                input.remove();
              });
              // 添加到DOM中才能触发点击
              document.body.append(input);
              input.click();
            },
          },
        },
      },
      table: {
        striped: true,
        rowKey: 'id',
        rowSelection: {
          type: 'checkbox',
          selectedRowKeys,
          onChange: (changed: string[]) => {
            selectedRowKeys.value = changed;
          },
        },
      },
      rowHandle: {
        buttons: {
          edit: { show: hasPermission(permCode.edit) },
          view: {
            dropdown: true,
            show: true,
            click(context) {
              push({
                name: RouteEnum.TENANT_VIEW,
                params: { id: context.row.id },
              });
            },
          },
          remove: { show: hasPermission(permCode.delete) },
          copy: { show: false },
          audit: {
            show: compute((context: ComputeContext) => {
              return (
                hasPermission(permCode.toExamine) &&
                [TenantStatusEnum.WAITING].includes(context.row?.status)
              );
            }),
            text: '审核',
            size: 'small',
            type: 'link',
            dropdown: true,
            click(context) {
              props.context.toExamineRef.value?.setData({
                record: context.row,
              });
              props.context.toExamineRef.value?.open();
            },
          },
          datasourceInit: {
            show: compute((context: ComputeContext) => {
              return (
                MultiTenantTypeEnum.DATASOURCE_COLUMN ===
                  VITE_GLOB_TENANT_TYPE &&
                hasPermission(permCode.initData) &&
                [TenantStatusEnum.WAIT_INIT_SCHEMA].includes(
                  context.row?.status,
                )
              );
            }),
            dropdown: true,
            text: '结构初始化',
            size: 'small',
            type: 'link',
            click(context) {
              props.context.initDataRef.value?.setData({ record: context.row });
              props.context.initDataRef.value?.open();
            },
          },
          datasourceLinkDataSourceDrawer: {
            // 数据源模式 && 有权限 && 特定status下显示此按钮
            show: compute((context: ComputeContext) => {
              return (
                MultiTenantTypeEnum.DATASOURCE_COLUMN ===
                  VITE_GLOB_TENANT_TYPE &&
                hasPermission(permCode.initDataSource) &&
                [
                  TenantStatusEnum.AGREED,
                  TenantStatusEnum.NORMAL,
                  TenantStatusEnum.WAIT_INIT_DATASOURCE,
                ].includes(context.row?.status)
              );
            }),
            dropdown: true,
            text: '数据源初始化',
            type: 'link',
            size: 'small',
            click(context) {
              props.context.linkDataSourceRef.value?.setData({
                record: context.row,
              });
              props.context.linkDataSourceRef.value?.open();
            },
          },
          columnInit: {
            dropdown: true,
            show: compute((context: ComputeContext) => {
              return (
                VITE_GLOB_TENANT_TYPE === MultiTenantTypeEnum.COLUMN &&
                hasPermission(permCode.initData) &&
                [TenantStatusEnum.WAIT_INIT_SCHEMA].includes(
                  context.row?.status,
                )
              );
            }),
            text: '结构初始化',
            size: 'small',
            type: 'link',
            click(context) {
              createConfirm({
                iconType: 'warning',
                content: '确认要初始化企业的初始数据吗？',
                onOk: async () => {
                  const flag = await DefTenantApi.initData({
                    id: context.row.id,
                  });
                  if (flag) {
                    createMessage.success(
                      '初始化企业成功，请尽快为企业绑定管理员',
                    );
                    props.crudExpose.doRefresh();
                  }
                },
              });
            },
          },
          bind: {
            dropdown: true,
            show: compute((context: ComputeContext) => {
              return (
                hasPermission(permCode.bindUser) &&
                [TenantStatusEnum.NORMAL].includes(context.row?.status)
              );
            }),
            type: 'link',
            text: '绑定管理员',
            size: 'small',
            click(context) {
              props.context.bindUserRef.value?.setData({
                record: context.row,
              });
              props.context.bindUserRef.value?.open();
            },
          },
        },
      },
      columns: {
        ...indexColumn(props.crudExpose),
        logo: {
          title: 'logo',
          type: 'cropper-uploader',
          form: {
            component: {
              valueType: 'key',
              buildUrl: async (res: any) => {
                const file = await asyncFindUrlById(res);
                return file.data;
              },
              uploader: {
                param: {
                  bizType: FileBizTypeEnum.DEF_TENANT_LOGO,
                },
              },
            },
            col: { span: 24 },
          },
          column: { show: false, columnSetDisabled: true },
        },
        creditCode: {
          title: $t('devOperation.tenant.defTenant.creditCode'),
          type: 'text',
          column: { show: false },
        },
        name: {
          title: $t('devOperation.tenant.defTenant.name'),
          type: 'text',
          search: { show: true },
        },
        registerType: {
          title: $t('devOperation.tenant.defTenant.registerType'),
          type: 'dict-radio',
          dict: backendDict({
            type: DictEnum.DefTenantRegisterTypeEnum,
          }),
          form: { show: false },
          viewForm: { show: true },
          column: { width: 80 },
        },
        abbreviation: {
          title: $t('devOperation.tenant.defTenant.abbreviation'),
          type: 'text',
          column: { show: false },
        },

        expirationTime: {
          title: $t('devOperation.tenant.defTenant.expirationTime'),
          type: 'datetime',
          form: {
            helper: {
              text: '有效期为空表示永久有效',
            },
            component: {
              format: 'YYYY-MM-DD HH:mm:ss',
              valueFormat: 'YYYY-MM-DD HH:mm:ss',
            },
          },
          valueBuilder({ value, row, key }) {
            if (value !== null && row) {
              row[key] = value;
            }
          },
          column: {
            width: 180,
            show: true,
            formatter: (context: ScopeContext) => {
              const record = context.row;
              if (record.expirationTime) {
                if (dateUtil(record.expirationTime).isBefore(Date.now())) {
                  return <Tag color="error">已过期</Tag>;
                } else if (
                  dateUtil(record.expirationTime).isBefore(
                    dateUtil().add(30, 'days'),
                  )
                ) {
                  const duration = dateUtil.duration(
                    dateUtil(record.expirationTime).diff(Date.now()),
                  );
                  if (duration.days() > 0) {
                    return (
                      <Tag color="warning">{duration.days() + 1}天后到期</Tag>
                    );
                  }
                  return (
                    <Tag color="warning">{duration.hours()}小时后到期</Tag>
                  );
                }
                return <Tag color="processing">{record.expirationTime}</Tag>;
              }

              return <Tag color="success">永久有效</Tag>;
            },
          },
        },
        state: {
          title: $t('devOperation.tenant.defTenant.state'),
          type: 'dict-radio',
          dict: STATE_CONSTANT_DICT,
          search: { show: true },
          addForm: { value: true },
          form: { component: { optionName: 'a-radio-button' } },
          column: { width: 80 },
        },

        contactPerson: {
          title: $t('devOperation.tenant.defTenant.contactPerson'),
          type: 'text',
          column: { show: false },
        },
        contactPhone: {
          title: $t('devOperation.tenant.defTenant.contactPhone'),
          type: 'text',
          column: { show: false },
        },
        contactEmail: {
          title: $t('devOperation.tenant.defTenant.contactEmail'),
          type: 'text',
          column: { show: false },
        },
        area: {
          title: '地区',
          type: 'text',
          column: { show: false },
          form: {
            component: {
              name: 'a-cascader',
              options: cities,
              checkStrategy: 'child',
            },
          },
        },
        address: {
          title: $t('devOperation.tenant.defTenant.address'),
          type: 'text',
          column: { show: false },
        },
        longitude: {
          title: $t('devOperation.tenant.defTenant.longitude'),
          type: 'text',
          column: { show: false },
        },
        latitude: {
          title: $t('devOperation.tenant.defTenant.latitude'),
          type: 'text',
          column: { show: false },
        },
        businessTime: {
          title: $t('devOperation.tenant.defTenant.businessTime'),
          type: 'text',
          column: { show: false },
        },
        status: {
          title: $t('devOperation.tenant.defTenant.status'),
          type: 'dict-select',
          dict: backendDict({
            type: DictEnum.DefTenantStatusEnum,
          }),
          search: { show: true },
          form: { show: false },
          column: { show: true, width: 120 },
        },

        describe: {
          title: $t('devOperation.tenant.defTenant.describe'),
          type: 'textarea',
          column: { show: false },
        },
        ...createdTimeColumn({}),
      },
    },
  };
}
